package mallindex

import (
	"context"
	// "fmt"
	"strconv"
	"strings"

	"mall/common/globalkey"
	"mall/common/jwt"
	"mall/common/utils/pointy"
	"mall/service/backend/rpc/backendclient"
	"mall/service/forum/api/internal/svc"
	"mall/service/forum/api/internal/types"
	"mall/service/forum/api/internal/utils/parse"
	"mall/service/product/rpc/productclient"

	// "github.com/sirupsen/logrus"
	"github.com/zeromicro/go-zero/core/logx"
)

type GetCorridorListLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewGetCorridorListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetCorridorListLogic {
	return &GetCorridorListLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *GetCorridorListLogic) GetCorridorList(
	req *types.GetCorridorListReq,
	headers *[]*types.Header,
) (resp *types.GetCorridorListResp, err error) {
	userId := jwt.GetUserId(l.ctx)

	page, pageSize := parse.ParsePageInfo(
		req.Current,
		req.PageSize,
		l.svcCtx.Config.Query.DefaultAmount,
		l.svcCtx.Config.Query.MaxAmount,
	)

	preload := "section:Id,Title,Subtitle,PicUrl"
	eagerLoad := "section:sectionProduct"
	preload += ";sectionProduct:SectionId,BrandId,CategoryId,ProductId"
	var filters []string
	filters = append(filters, "Status,equalTo:"+strconv.FormatInt(int64(globalkey.StatusEnabled), 10))
	filters = append(filters, "Type,equalTo:"+strconv.FormatInt(int64(globalkey.SettingSectionTypeCorridorIndex), 10))

	res, err := l.svcCtx.BackendRpc.GetSectionList(l.ctx, &backendclient.BaseListReq{
		Offset:     uint32((page - 1) * pageSize),
		Limit:      uint32(pageSize),
		Preload:    pointy.GetPointer(preload),
		EagerLoad:  pointy.GetPointer(eagerLoad),
		Filter:     pointy.GetPointer(strings.Join(filters, ";")),
		VisitorId:  pointy.GetPointer(userId),
		PlatformId: pointy.GetPointer(globalkey.ThirdPartyPlatformWechatMini),
	})
	if err != nil {
		return nil, err
	}

	var hasNextPage bool
	var hasPreviousPage bool
	if res.HasNextPage != nil && *res.HasNextPage > 0 {
		hasNextPage = true
	}
	if res.HasPreviousPage != nil && *res.HasPreviousPage > 0 {
		hasPreviousPage = true
	}
	resp = &types.GetCorridorListResp{
		BaseListInfo: types.BaseListInfo{
			HasNextPage:     hasNextPage,
			HasPreviousPage: hasPreviousPage,
		},
	}

	if len(res.List) > 0 {
		idTermMap := make(map[uint64][]*types.TermInfo)
		for _, v := range res.List {
			if v.Id != nil && *v.Id > 0 {
				var tids []string
				for pid, pType := range v.ProductIdMap {
					switch pType {
					case 3:
						tids = append(tids, strconv.FormatUint(pid, 10))
					}
				}

				if len(tids) > 0 {
					tags, err := l.getProductTagListByIds(tids)
					if err != nil {
						return nil, err
					}

					if len(tags) > 0 {
						idTermMap[*v.Id] = append(idTermMap[*v.Id], tags...)
					}
				}
			}
		}

		for _, v := range res.List {
			var tagList []*types.TermInfo
			if v.Id != nil && *v.Id > 0 {
				if list, ok := idTermMap[*v.Id]; ok {
					tagList = list[:]
				}
			}

			resp.List = append(resp.List, &types.GoodsTagSectionInfo{
				Id:       v.Id,
				Title:    v.Title,
				Subtitle: v.Subtitle,
				ImageUrl: v.PicUrl,
				TagList:  tagList,
			})
		}

		*headers = []*types.Header{
			{
				Key:   "x-class",
				Value: "com.djx.appview.MallIndexPage",
			},
		}
	}

	return resp, nil
}

func (l *GetCorridorListLogic) getProductTagListByIds(tids []string) (resp []*types.TermInfo, err error) {
	preload := "productTerm:Id,Name,Slug"
	eagerLoad := "productTerm:productTermMeta,productMedia"
	preload += ";productTermMeta:mediaId,mediaUrl"
	preload += ";productMedia:Uid,Url"

	var filters []string
	filters = append(filters, "Status,equalTo:"+strconv.FormatInt(int64(globalkey.StatusEnabled), 10))
	filters = append(filters, "Id,in:"+strings.Join(tids, ","))

	res, err := l.svcCtx.ProductRpc.GetTermList(l.ctx, &productclient.BaseListReq{
		Preload:   pointy.GetPointer(preload),
		EagerLoad: pointy.GetPointer(eagerLoad),
		Filter:    pointy.GetPointer(strings.Join(filters, ";")),
	})
	if err != nil {
		return nil, err
	}

	if len(res.List) > 0 {
		for _, v := range res.List {
			// logrus.Info(fmt.Sprintf("GetCorridorList getProductListByIds GetProductList res.List: %+v", v))
			var mediaUrl *string
			if len(v.Meta) > 0 {
				for _, m := range v.Meta {
					if m.Key == nil || m.Value == nil {
						continue
					}

					val := *m.Value
					switch *m.Key {
					case "mediaUrl":
						mediaUrl = pointy.GetPointer(val)
					}
				}
			}

			if len(v.Media) > 0 {
				for _, m := range v.Media {
					if mediaUrl != nil {
						break
					}

					var url string
					if m.Url != nil && len(*m.Url) > 0 {
						url = *m.Url
					}
					if len(url) == 0 && m.Uri != nil && len(*m.Uri) > 0 {
						url = *m.Uri
					}
					mediaUrl = pointy.GetPointer(url)
				}
			}

			resp = append(resp, &types.TermInfo{
				Id:   v.Id,
				Name: v.Name,
				Slug: v.Slug,
				// Content:  v.Desc,
				ImageUrl: mediaUrl,
			})
		}
	}

	return resp, nil
}
